﻿#include<stdio.h>
#include <string.h>
#include"aacenc_lib.h"
#include"WavFileReader.h"

void MonoToStereo(const int16_t* src_audio,int frames,int16_t* dst_audio) 
{
	int i = 0;
    for (i = 0; i < frames; i++) 
    {
        dst_audio[2 * i] = src_audio[i];
        dst_audio[2 * i + 1] = src_audio[i];
    }
}

int main(int argc, char* argv[])
{
	FILE* f = nullptr;
	AC::WavFileReader wr;
	HANDLE_AACENCODER encoder = nullptr;
	unsigned char buffer1[2048] = {0}, buffer2[4096] = {0};
	int readBytes = -1;
	AACENC_InfoStruct info = { 0 };
	int16_t *convert_buf = (int16_t*)malloc(4096);
	int16_t *dst_buf = (int16_t*)malloc(4096);
	//打开文件
	f = fopen("./out.aac", "wb+");
	if (!f)
	{
		goto end;
	}
	if (!wr.OpenWavFile("out.wav"))
	{
		goto end;
	}
	//初始化编码器
	if (aacEncOpen(&encoder, 1, 2) != AACENC_OK) {
		return -1;
	}
	if (aacEncoder_SetParam(encoder, AACENC_SAMPLERATE, 48000) != AACENC_OK) {
		printf("set samplerate error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_BITRATE, 320 * 1000) != AACENC_OK) {
		printf("set bitrate error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_SBR_MODE, 1) != AACENC_OK) {
		printf("set sbr_mode error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_SBR_RATIO, 1) != AACENC_OK) {
		printf("set sbr_mode error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_AOT, AOT_AAC_LC) != AACENC_OK) {
		printf("set aot error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_CHANNELMODE, MODE_2) != AACENC_OK) {
		printf("set channelmode error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_CHANNELORDER, 1) != AACENC_OK) {
		printf("set channelorder error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_BITRATEMODE, 0) != AACENC_OK) {
		printf("set bitratemode error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_TRANSMUX, 2) != AACENC_OK) {
		printf("set transmux error!\n");
		goto end;
	}
	if (aacEncoder_SetParam(encoder, AACENC_HEADER_PERIOD, 2) != AACENC_OK) {
		printf("set transmux error!\n");
		goto end;
	}
	if (aacEncEncode(encoder, nullptr, nullptr, nullptr, nullptr) != AACENC_OK)
	{
		printf("set transmux error!\n");
		goto end;
	}
	if (aacEncInfo(encoder, &info) != AACENC_OK)
	{
		printf("set transmux error!\n");
		goto end;
	}
	printf("%d\n", aacEncoder_GetParam(encoder, AACENC_BITRATE));
	printf("%d\n", info.frameLength);
	do {
		int i = 0;
		readBytes = wr.ReadData(buffer1, 2048);
		//covert to 16bit
		for (i = 0; i < readBytes/2; i++) 
		{
			const uint8_t* in = &buffer1[2*i];
			convert_buf[i] = in[0] | (in[1] << 8);
		}

		int len = readBytes / 2;
		MonoToStereo(convert_buf, len, dst_buf);
		AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
		AACENC_InArgs in_args = { 0 ,0 };
		AACENC_OutArgs out_args = { 0 };
		int in_identifier = IN_AUDIO_DATA;
		int in_elem_size = 2;
		void* in_ptr = dst_buf;
		int out_identifier = OUT_BITSTREAM_DATA;
		int out_size = 4096;
		int out_elem_size = 1;
		void* out_ptr = buffer2;

		int size = readBytes * 2;
		in_args.numInSamples = readBytes;			//frame length
		in_buf.bufs = (void**)&in_ptr;
		in_buf.numBufs = 1;
		in_buf.bufferIdentifiers = &in_identifier;
		in_buf.bufSizes = &readBytes;		//size or readBytes?
		in_buf.bufElSizes = &in_elem_size;
		
		out_buf.numBufs = 1;
		out_buf.bufs = (void**)&out_ptr;
		out_buf.bufferIdentifiers = &out_identifier;
		out_buf.bufSizes = &out_size;
		out_buf.bufElSizes = &out_elem_size;
		//编码
		if ((aacEncEncode((encoder), &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) {
			printf("encode error!\n");
			goto end;
		}
		if (out_args.numOutBytes > 0)
			//写入文件
		{
			fwrite(buffer2, 1, out_args.numOutBytes, f);
		}
	} while (readBytes > 0);
end:
	if (encoder)
	{
		aacEncClose((HANDLE_AACENCODER*)(&encoder));
	}
	if (f)
	{
		fclose(f);
	}
	if (convert_buf)
	{
		free(convert_buf);
	}
	if (dst_buf)
	{
		free(dst_buf);
	}
	return 0;
}